#include "stdafx.h"
#include "HexParser.h"

namespace AppliedCryptography
{
	byte HexParser::EncodeChar(char chr) const
	{
		if(chr >= '0' && chr <= '9')
			return chr-'0';

		if(chr >= 'A' && chr <= 'F')
			return chr-'A'+10;

		if(chr >= 'a' && chr <= 'f')
			return chr-'a'+10;

		return 0;
	};

	std::string HexParser::DecodeByte(byte b) const
	{
		std::string result;
		char c[2];
		char t[2];

		c[1] = b % 16;
		c[0] = (b - c[1]) / 16;

		t[1]  = '\0';

		for(int i = 0; i < 2; i++)
		{
			if(c[i] < 10)
			{
				t[0] = (char)c[i] + '0';
				result.append(t);
			}
			else
			{
				t[0] = (char)(c[i] + (IsUpperCaseMode() ? 'A' : 'a') - 10);
				result.append(t);
			};
		};

		return result;
	};

	std::vector<byte> HexParser::operator()(const char* input) const
	{
		return this->Encode(input);
	};

	std::vector<byte> HexParser::operator()(std::string& input) const
	{
		return this->Encode(input);
	};

	std::vector<byte> HexParser::Encode(const char* input) const
	{
		std::string str(input);
		return this->Encode(str);
	};

	std::vector<byte> HexParser::Encode(std::string& input) const
	{
		byte b1, b2;
		std::vector<byte> result;
		unsigned int len = input.length() / 2;

		for(unsigned int i=0; i < len; ++i)
		{
			b1 = EncodeChar(input.c_str()[i*2]);
			b2 = EncodeChar(input.c_str()[i*2+1]);
			result.push_back(b1 * 16 + b2);
		};

		return result;
	};

	std::string HexParser::operator()(std::vector<byte>& input) const
	{
		return this->Decode(input);
	};

	std::string HexParser::Decode(std::vector<byte>& input) const
	{
		std::string result;

		for(unsigned int i = 0; i < input.size(); ++i)
		{
			result.append(this->DecodeByte(input.at(i)));
		};

		return result;
	};

	bool HexParser::IsUpperCaseMode() const
	{
		return _upperCase;
	};

	void HexParser::SetUpperCaseMode(bool mode)
	{
		_upperCase = mode;
	};
};
